//
//  EpointWebServiceUtil.m
//  EpointFrame5
//
//  Created by 李亚春 on 13-12-17.
//  Copyright (c) 2013年 Epoint. All rights reserved.
//

#import "EpointWebServiceUtil.h"
#import "GDataXMLNode.h"


@implementation EpointWebServiceUtil{
    NSMutableData * responseData;
}

-(id)initWithUrl:(NSString *)ws_url namespace:(NSString *)_namespace method:(NSString *)_method
{
    self.wsurl = ws_url;
    self.wsmethod = _method;
    self.wsnamespace = _namespace;
    self.funpars = [[NSMutableString alloc]initWithString:@""];
    return self;
}

-(NSString *)start
{
    NSString* message = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><%@ xmlns=\"%@\">%@</%@></soap:Body></soap:Envelope>",self.wsmethod,self.wsnamespace,self.funpars,self.wsmethod];
    NSString* mesLenth = [NSString stringWithFormat:@"%lu",(unsigned long)message.length];
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.wsurl]];
    
    [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request addValue:[NSString stringWithFormat:@"%@%@",self.wsnamespace,self.wsmethod] forHTTPHeaderField:@"SOAPAction"];
    [request addValue:mesLenth forHTTPHeaderField:@"Content-Length"];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[message dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSError *error;
    NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
//    NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
//    NSLog(@"%@",str);
    GDataXMLDocument* _GDataParse = [[GDataXMLDocument alloc]initWithData:data  options:0 error:&error];
    if(error)
    {
        return nil;
    }
    GDataXMLElement* element =[[[[[_GDataParse.rootElement.children objectAtIndex:0] children]objectAtIndex:0] children] objectAtIndex:0];
    return element.stringValue;
}


//start－－－－－－－－－－－－－－－－－－－－－－调用https协议的方法－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
-(NSString *)starts:(NSString*)CertBase64
{
    NSString* message = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Header><CertficateSoapHeader xmlns=\"http://tempuri.org/\"><CertBase64>%@</CertBase64></CertficateSoapHeader></soap:Header><soap:Body><%@ xmlns=\"%@\">%@</%@></soap:Body></soap:Envelope>",CertBase64,self.wsmethod,self.wsnamespace,self.funpars,self.wsmethod];
    NSString* mesLenth = [NSString stringWithFormat:@"%lu",(unsigned long)message.length];
    NSMutableURLRequest* request =[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:self.wsurl]        cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:5];
    
    [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request addValue:[NSString stringWithFormat:@"%@%@",self.wsnamespace,self.wsmethod] forHTTPHeaderField:@"SOAPAction"];
    [request addValue:mesLenth forHTTPHeaderField:@"Content-Length"];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[message dataUsingEncoding:NSUTF8StringEncoding]];
    finished=NO;
    responseData = [[NSMutableData alloc] init];
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    //堵塞线程，等待结束
    while(!finished) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
     NSError *error;
    GDataXMLDocument* _GDataParse = [[GDataXMLDocument alloc]initWithData:responseData  options:0 error:&error];
    if(error)
    {
        return nil;
    }
    GDataXMLElement* element =[[[[[_GDataParse.rootElement.children objectAtIndex:0] children]objectAtIndex:0] children] objectAtIndex:0];
    
    NSLog(@"responseStr=%@",element.stringValue);
    return element.stringValue;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response
{
    NSLog(@"response");
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"connectionDidFinishLoading");
    finished=YES;
}
//数据返回结束并调用成功，回调方法
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    finished=YES;
    NSLog(@"didFailWithError");
}
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection{
    return NO;
}
//下面两段是重点，要服务器端单项HTTPS 验证，iOS 客户端忽略证书验证。
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    NSLog(@"didReceiveAuthenticationChallenge %@ %zd", [[challenge protectionSpace] authenticationMethod], (ssize_t) [challenge previousFailureCount]);
    
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){
        [[challenge sender]  useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
        [[challenge sender]  continueWithoutCredentialForAuthenticationChallenge: challenge];
    }
    NSLog(@"get the whole response");

}
//处理数据
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
     NSLog(@"connection data=%@",data);
    responseData=(NSMutableData*)data;
}

//end－－－－－－－－－－－－－－－－－－－－－－调用https协议的方法－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－

-(void)addParameterForString:(NSString *)name value:(NSString *)value
{
    [self.funpars appendFormat:@"<%@>%@</%@>",name,value,name];
}

-(void)addParameterForInteger:(NSString *)name value:(int)value
{
    [self.funpars appendFormat:@"<%@>%i</%@>",name,value,name];
}

/*
 //Mark: 生成SOAP1.1版本的ASIHttp请求
 参数 webURL：                远程WebService的地址，不含*.asmx
 参数 webServiceFile：        远程WebService的访问文件名，如service.asmx
 参数 xmlNS：                    远程WebService的命名空间
 参数 webServiceName：        远程WebService的名称
 参数 wsParameters：            调用参数数组，形式为[参数1名称，参数1值，参数2名称，参数2值⋯⋯]，如果没有调用参数，此参数为nil
 */
+ (ASIHTTPRequest *)getASISOAP11Request:(NSString *) WebURL
                         webServiceFile:(NSString *) wsFile
                           xmlNameSpace:(NSString *) xmlNS
                         webServiceName:(NSString *) wsName
                           wsParameters:(NSMutableArray *) wsParas
{
    //1、初始化SOAP消息体
    NSString * soapMsgBody1 = [[NSString alloc] initWithFormat:
                               @"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
                               "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n"
                               "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \n"
                               "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
                               "<soap:Body>\n"
                               "<%@ xmlns=\"%@\">\n", wsName, xmlNS];
    NSString * soapMsgBody2 = [[NSString alloc] initWithFormat:
                               @"</%@>\n"
                               "</soap:Body>\n"
                               "</soap:Envelope>", wsName];
    
    //2、生成SOAP调用参数
    NSString * soapParas = [[NSString alloc] init];
    soapParas = @"";
    if (![wsParas isEqual:nil]) {
        int i = 0;
        for (i = 0; i < [wsParas count]; i = i + 2) {
            soapParas = [soapParas stringByAppendingFormat:@"<%@>%@</%@>\n",
                         [wsParas objectAtIndex:i],
                         [wsParas objectAtIndex:i+1],
                         [wsParas objectAtIndex:i]];
        }
    }
    
    //3、生成SOAP消息
    NSString * soapMsg = [soapMsgBody1 stringByAppendingFormat:@"%@%@", soapParas, soapMsgBody2];
    
    //请求发送到的路径
    NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", WebURL, wsFile]];
    
    //NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
    ASIHTTPRequest * theRequest = [ASIHTTPRequest requestWithURL:url];
    NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMsg length]];
    
    //以下对请求信息添加属性前四句是必有的，第五句是soap信息。
    [theRequest addRequestHeader:@"Content-Type" value:@"text/xml; charset=utf-8"];
    [theRequest addRequestHeader:@"SOAPAction" value:[NSString stringWithFormat:@"%@%@", xmlNS, wsName]];
    
    [theRequest addRequestHeader:@"Content-Length" value:msgLength];
    [theRequest setRequestMethod:@"POST"];
    [theRequest appendPostData:[soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
    
    [theRequest setDefaultResponseEncoding:NSUTF8StringEncoding];
    
    return theRequest;
}

#pragma mark -
/*
 //Mark: 使用SOAP1.1同步调用WebService请求
 参数 webURL：                远程WebService的地址，不含*.asmx
 参数 webServiceFile：        远程WebService的访问文件名，如service.asmx
 参数 xmlNS：                    远程WebService的命名空间
 参数 webServiceName：        远程WebService的名称
 参数 wsParameters：            调用参数数组，形式为[参数1名称，参数1值，参数2名称，参数2值⋯⋯]，如果没有调用参数，此参数为nil
 */
+ (NSString *)getSOAP11WebServiceResponse:(NSString *) WebURL
                           webServiceFile:(NSString *) wsFile
                             xmlNameSpace:(NSString *) xmlNS
                           webServiceName:(NSString *) wsName
                             wsParameters:(NSMutableArray *) wsParas
{
    //创建请求
    ASIHTTPRequest * theRequest = [self getASISOAP11Request:WebURL
                                             webServiceFile:wsFile
                                               xmlNameSpace:xmlNS
                                             webServiceName:wsName
                                               wsParameters:wsParas];
    
    //显示网络请求信息在status bar上
    [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:YES];
    
    //同步调用
    [theRequest startSynchronous];
    NSError *error = [theRequest error];
    if (!error) {
        return [theRequest responseString];
    }
    else {
        //出现调用错误，则使用错误前缀+错误描述
        return [NSString stringWithFormat:@"%@", [error localizedDescription]];
    }
}

#pragma mark -
/*
 //Mark: 使用SOAP1.1同步调用WebService请求，需提供Windows集成验证的用户名、密码和域
 参数 webURL：                远程WebService的地址，不含*.asmx
 参数 webServiceFile：        远程WebService的访问文件名，如service.asmx
 参数 xmlNS：                    远程WebService的命名空间
 参数 webServiceName：        远程WebService的名称
 参数 wsParameters：            调用参数数组，形式为[参数1名称，参数1值，参数2名称，参数2值⋯⋯]，如果没有调用参数，此参数为nil
 参数 userName                用户名--目前来看，不需要输入域信息
 参数 passWord                密码
 */
+ (NSString *)getSOAP11WebServiceResponseWithNTLM:(NSString *) WebURL
                                   webServiceFile:(NSString *) wsFile
                                     xmlNameSpace:(NSString *) xmlNS
                                   webServiceName:(NSString *) wsName
                                     wsParameters:(NSMutableArray *) wsParas
                                         userName:(NSString *) userName
                                         passWord:(NSString *) passWord
{
    //创建请求
    ASIHTTPRequest * theRequest = [self getASISOAP11Request:WebURL
                                             webServiceFile:wsFile
                                               xmlNameSpace:xmlNS
                                             webServiceName:wsName
                                               wsParameters:wsParas];
    
    //集成验证NTLM用户名，密码和域设置
    [theRequest setUsername:userName];
    [theRequest setPassword:passWord];
    //[theRequest setDomain:doMain];
    
    //显示网络请求信息在status bar上
    [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:YES];
    
    //同步调用
    [theRequest startSynchronous];
    NSError *error = [theRequest error];
    if (!error) {
        return [theRequest responseString];
    }
    else {
        //出现调用错误，则使用错误前缀+错误描述
        return [NSString stringWithFormat:@"%@",[error localizedDescription]];
    }
}


@end
